package com.xci.edu.core.service;

import com.github.lvyanyang.core.BaseService;
import com.github.lvyanyang.core.BoolResult;
import com.github.lvyanyang.core.XCI;
import com.xci.edu.core.dao.ExamPaperDao;
import com.xci.edu.core.dao.ExamPaperDetailsDao;
import com.xci.edu.core.entity.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 学员考试服务
 * @author 马星俊 maxingjun@xci96716.com
 * @since 2020-11-25 10:52:08
 */
@Service
public class ExamService extends BaseService {
    /** 学员服务 */
    @Resource private EduStudentService eduStudentService;
    /** 考试预约服务 */
    @Resource private ExamPreService examPreService;
    /** 考试记录服务 */
    @Resource private ExamRecordService examRecordService;
    /** 考试记录服务 */
    @Resource private ExamRecordDetailsService examRecordDetailsService;
    /** 试卷信息服务 */
    @Resource private ExamPaperService examPaperService;
    /** 试题库服务 */
    @Resource private EduQuestionService eduQuestionService;
    /** 试卷信息数据层对象 */
    @Resource private ExamPaperDao examPaperDao;
    /** 试卷试题明细数据层对象 */
    @Resource private ExamPaperDetailsDao examPaperDetailsDao;

    /**
     * 根据学员主键查询当前时间所有的考试预约记录
     * @param studentId 学员主键
     * @return 返回考试记录实体
     */
    public List<ExamPre> selectByStudentId(@NotNull(message = "请指定学员主键") Long studentId) {
        return examPreService.selectByStudentId(studentId);
    }

    /**
     * 新建考试记录,考试记录明细
     * @param paperId 试卷主键
     * @param studentId 学员主键
     */
    @Transactional(rollbackFor = Exception.class)
    public BoolResult insert(@NotNull(message = "请指定试卷主键") Long paperId,
                             @NotNull(message = "请指定学员主键") Long studentId) {
        //新建考试记录
        var result = saveExamRecord(paperId, studentId);
        //新建考试记录明细
        return saveExamRecordDetails((ExamRecord)(result.getData()));
    }

    /**
     * 查询考试试题
     * @param paperId 考试记录主键
     * @param recordId 考试记录主键
     */
    public List<ExamQuestion> selectQuestionByRecordId(@NotNull(message = "请指定试卷主键") Long paperId,
                                                      @NotNull(message = "请指定考试记录主键") Long recordId) {
        ExamPaper examPaper = examPaperService.selectById(paperId);
        //试题集
        List<ExamQuestion> examQuestionList = examRecordDetailsService.selectQuestionByRecordId(recordId);
        //试题选项排序
        if (examPaper.getQuestionOptionOrder()!=0){
            for (ExamQuestion item: examQuestionList) {
                Map option = new TreeMap();
                XCI.ifNotBlankAction(item.getOptionA(),()->option.put("A",item.getOptionA()));
                XCI.ifNotBlankAction(item.getOptionB(),()->option.put("B",item.getOptionB()));
                XCI.ifNotBlankAction(item.getOptionC(),()->option.put("C",item.getOptionC()));
                XCI.ifNotBlankAction(item.getOptionD(),()->option.put("D",item.getOptionD()));
                XCI.ifNotBlankAction(item.getOptionE(),()->option.put("E",item.getOptionE()));
                XCI.ifNotBlankAction(item.getOptionF(),()->option.put("F",item.getOptionF()));

                HashMap<String,String> newOption = random(option,item.getAnswer());
                for (int i=0;i<newOption.size()-1;i++){
                    switch (i){
                        case 0:
                            item.setOptionA(newOption.get(c[i]));
                            break;
                        case 1:
                            item.setOptionB(newOption.get(c[i]));
                            break;
                        case 2:
                            item.setOptionC(newOption.get(c[i]));
                            break;
                        case 3:
                            item.setOptionD(newOption.get(c[i]));
                            break;
                        case 4:
                            item.setOptionE(newOption.get(c[i]));
                            break;
                        case 5:
                            item.setOptionF(newOption.get(c[i]));
                            break;
                    }
                }
                item.setAnswer(newOption.get("answer"));
            }
        }
        //试题排序
        if (examPaper.getQuestionOrder()!=0){
            Collections.shuffle(examQuestionList);
        }
        return examQuestionList;
    }

    /**
     * 记录答题情况
     */
    public BoolResult updateRecordDetails(ExamRecordDetails entity){
        return examRecordDetailsService.update(entity);
    }

    /**
     * 记录考试结果
     * @param recordId 考试记录主键
     * @param passScore 及格分数
     */
    public BoolResult updateExam(Long recordId,Integer passScore){

        Integer score = examRecordDetailsService.selectScoreByRecordId(recordId);
        ExamRecord examRecord = examRecordService.selectById(recordId);
        examRecord.setExamScore(score);
        int result = score>=passScore ? 1: 0;
        examRecord.setExamResult(result);
        examRecord.setExamEndDateTime(XCI.now());
        Long diff = (XCI.now().getTime()-examRecord.getExamStartDateTime().getTime())/60/1000;
        examRecord.setExamDuration(diff.intValue());
        examRecordService.update(examRecord);
        return BoolResult.success(result);
    }

    private String[] c={"A","B","C","D","E","F"};

    /**
     * 对试题选项和答案进行打乱排序
     * @param option 原选项
     * @param key   答案
     * @return 新选项
     */
    private HashMap<String, String> random(Map<String, String> option, String key){
        //获取key值
        Set<String> keySet = option.keySet();
        //将set转换成List
        ArrayList<String> keyList = new ArrayList<String>(keySet);
        //打乱List
        Collections.shuffle(keyList);
        HashMap<String, String> newOption = new HashMap<String, String>();
        int idx = 0;
        StringBuffer keyNew = new StringBuffer("");
        for (String next: keySet){
            String randomKey = keyList.get(idx++);
            if(key.contains(next)){
                keyNew.append(randomKey);
            }
            newOption.put(randomKey, option.get(next));
        }
        newOption.put("answer",String.valueOf(keyNew));
        return newOption;
    }


    /**
     * 新建考试记录
     * @param paperId 试卷主键
     * @param studentId 学员主键
     * @return 返回考试记录实体
     */
    private BoolResult saveExamRecord(Long paperId, Long studentId) {
        //获取学员对象
        EduStudent eduStudent = eduStudentService.selectById(studentId);
        //获取学员当前考试的试卷对象
        ExamPaper examPaper = examPaperService.selectById(paperId);

        //新建考试记录
        ExamRecord entity = new ExamRecord();
        entity.setStudentId(eduStudent.getId());
        entity.setStudentName(eduStudent.getName());
        entity.setStudentIdNumber(eduStudent.getIdNumber());
        entity.setPaperId(examPaper.getId());
        entity.setPaperName(examPaper.getName());
        entity.setEduCategoryId(eduStudent.getEduCategoryId());
        entity.setEduCategoryName(eduStudent.getEduCategoryName());
        entity.setStatus(0);
        return examRecordService.insert(entity);
    }

    /**
     * 新建考试记录明细
     * @param entity 考试记录实体
     * @return 返回结果
     */
    private BoolResult saveExamRecordDetails(ExamRecord entity) {
        //根据试卷Id获取该试卷具体信息
        ExamPaper paper = examPaperDao.selectById(entity.getPaperId());
        //根据试卷类别判断获取固定试题或随机生成
        List<ExamRecordDetails> list = new ArrayList<>();
        ExamRecordDetails recordDetails;
        switch (paper.getPaperCategory()){
            case 1:
                //普通试卷
                List<ExamPaperDetails> paperDetailsList = examPaperDetailsDao.selectListByPaperId(paper.getId());
                //循环所有试题，每道试题对应插入一条考试试题明细
                for (ExamPaperDetails item : paperDetailsList){
                    recordDetails = new ExamRecordDetails();
                    recordDetails.setRecordId(entity.getId());
                    recordDetails.setQuestionId(item.getQuestionId());
                    recordDetails.setPath(item.getPath());
                    list.add(recordDetails);
                }
                examRecordService.batchSave(list);
                break;
            case 2:
                //随机试卷
                List<EduQuestion> questionList = eduQuestionService.randomList(paper);
                for(int i=0;i<questionList.size();i++){
                    recordDetails = new ExamRecordDetails();
                    recordDetails.setRecordId(entity.getId());
                    recordDetails.setQuestionId(questionList.get(i).getId());
                    recordDetails.setPath(i);
                    list.add(recordDetails);
                }
                examRecordService.batchSave(list);
                break;
        }
        return BoolResult.success();
    }

    /**
     *
     */

}
